package com.jvyou.framework.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jvyou.common.constant.BaseConstants;
import com.jvyou.common.constant.RedisKey;
import com.jvyou.common.core.domain.entity.User;
import com.jvyou.common.core.domain.model.LoginUser;
import com.jvyou.common.core.domain.model.Result;
import com.jvyou.common.enums.result.HttpCodeEnum;
import com.jvyou.common.exception.AppException;
import com.jvyou.common.utils.bean.BeanCopyUtils;
import com.jvyou.framework.domain.dto.LoginDto;
import com.jvyou.framework.domain.vo.LoginVo;
import com.jvyou.framework.mapper.MenuMapper;
import com.jvyou.framework.mapper.RoleMapper;
import com.jvyou.framework.mapper.UserMapper;
import com.jvyou.framework.service.AuthService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

/**
 * @author 橘柚
 * @since 2025/5/29 17:12
 */
@Service("authService")
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {
    private final UserMapper userMapper;
    private final RoleMapper roleMapper;
    private final MenuMapper menuMapper;


    @Override
    public Result<LoginVo> doLogin(LoginDto loginDto) {
        // 1. 根据用户名查询用户
        LambdaUpdateWrapper<User> userWrapper = new LambdaUpdateWrapper<>();
        userWrapper.eq(User::getUsername, loginDto.getUsername());
        User user = userMapper.selectOne(userWrapper);
        // 2. 判断用户是否存在
        Optional.ofNullable(user).orElseThrow(() -> new AppException(HttpCodeEnum.USER_NOT_EXIST));
        if (user.getStatus().equals(BaseConstants.LOCK)) {
            throw new AppException(HttpCodeEnum.USER_LOCKED);
        }
        // 3. 校验密码
        boolean pwdRight = BCrypt.checkpw(loginDto.getPassword(), user.getPassword());
        if (!pwdRight) {
            throw new AppException(HttpCodeEnum.PASSWORD_NOT_RIGHT);
        }
        // 4. 登录
        StpUtil.login(user.getId());
        String token = StpUtil.getTokenValue();
        LoginUser loginUser = BeanCopyUtils.copyBean(user, LoginUser.class);
        List<String> roleList = roleMapper.getRoleByUserId(user.getId());
        List<String> permissionList = menuMapper.getPermissionByUserId(user.getId());
        loginUser.setPermissions(permissionList);
        loginUser.setRoles(roleList);
        StpUtil.getSession().set(RedisKey.LOGIN_USER_KEY + user.getId(), loginUser);
        // 5. 缓存用户信息
        return Result.success(new LoginVo(token));
    }
}
